// wtkfpscounter.hpp
//

#ifndef _WTKFPSCOUNTER_HPP
#define _WTKFPSCOUNTER_HPP

#include "wtk/wtkbase.hpp"

#include <chrono>

namespace wtk
{
  // FPSInfo
  //
  struct FPSInfo
  {
    size_t frame;
    double dtime;
    double fps;
  };


  
  // FPSCounter
  //
  template<size_t SAMPLE_COUNT>
  class WTK_API FPSCounter
  {
  public:
    FPSCounter ()
      : samples({}),
        samples_sum(std::chrono::duration<double>::zero())
    {
      // [FIXME]
      for (size_t i = 0; i < SAMPLE_COUNT; i++)
        {
          assert(samples[i].count() == 0.0f);
        }
      
      last_point = clock.now();
    }

    void step ( FPSInfo &info )
    {
      info.frame = ++frame;
      std::chrono::time_point<std::chrono::steady_clock> now = clock.now();
      std::chrono::duration<double> sample = now - last_point;
      last_point = now;
      samples_sum += sample;
      samples_sum -= samples[current_sample];
      samples[current_sample++] = sample;
      if (current_sample == SAMPLE_COUNT)
        current_sample = 0;

      info.dtime = sample.count();
      info.fps = ((double) std::min(frame, SAMPLE_COUNT)) / samples_sum.count();
    }
    
  private:
    std::chrono::steady_clock clock{};
    std::chrono::time_point<std::chrono::steady_clock> last_point{};
    std::array<std::chrono::duration<double>, SAMPLE_COUNT> samples{};
    size_t current_sample{0};
    std::chrono::duration<double> samples_sum{};
    size_t frame{0};
  };
}

#endif
